#include <func.h>

#define MONEY1 100
#define MONEY2 900

typedef struct
{
    int id;
    int money;
    pthread_mutex_t mutex;
}Account;

Account acct1 = {1,MONEY1,PTHREAD_MUTEX_INITIALIZER};
Account acct2 = {2,MONEY2,PTHREAD_MUTEX_INITIALIZER};

void lock(void)
{
    if(acct1.id < acct2.id)
    {
        pthread_mutex_lock(&acct1.mutex);
        sleep(1);
        pthread_mutex_lock(&acct2.mutex);
    }
    else
    {
        pthread_mutex_lock(&acct2.mutex);
        sleep(1);
        pthread_mutex_lock(&acct1.mutex);
    }
}

void* changeMoney1(void*)
{
    int change = MONEY1;

    lock();

    if(acct1.money < change)
    {
        pthread_mutex_unlock(&acct1.mutex);
        pthread_mutex_unlock(&acct2.mutex);
        return 0;
    }
        acct1.money -= change;
        sleep(2);
        sleep(1);
        acct2.money += change;

    printf("acct1.money: %d ,acct2.money: %d \n",acct1.money,acct2.money);

    pthread_mutex_unlock(&acct1.mutex);
    pthread_mutex_unlock(&acct2.mutex);

    return NULL;
}

void* changeMoney2(void*)
{
    int change = MONEY2;

    lock();

    if(acct2.money < change)
    {
        pthread_mutex_unlock(&acct1.mutex);
        pthread_mutex_unlock(&acct2.mutex);
        return 0;
    }
        acct2.money -= change;
        sleep(2);
        sleep(1);
        acct1.money += change;

    printf("acct1.money: %d ,acct2.money: %d \n",acct1.money,acct2.money);

    pthread_mutex_unlock(&acct1.mutex);
    pthread_mutex_unlock(&acct2.mutex);

    return NULL;
}

int main(int argc,char* argv[])
{
    pthread_t tid1,tid2;

    pthread_create(&tid1,NULL,changeMoney1,NULL);
    pthread_create(&tid2,NULL,changeMoney2,NULL);

    pthread_join(tid1,NULL);
    pthread_join(tid2,NULL);

    return 0;
}
